<script lang="ts" setup>
import { computed, getCurrentInstance, ref, unref, useAttrs, watch } from 'vue'
import { Icon } from '@iconify/vue'

import { isFunction } from 'lodash-es'

import type { Recordable } from '@/types/global'
import { deepMerge } from '@/utils/gloab'
import { ElDialog } from 'element-plus'

import DialigFooter from './components/DialogFooter.vue'
import { basicProps } from './props'
import type { BasicDialogProps, ModalMethods } from './types'

const props = defineProps(basicProps)
const emit = defineEmits(['cancel', 'ok', 'register', 'visible-change', 'close'])
const attrs = useAttrs()
const dialogVisible = ref<boolean>(false)
const propsRef = ref<null | Partial<BasicDialogProps>>(null)
const modalMethods: ModalMethods = {
  setModalProps,
  emitVisible: undefined,
}
const instance = getCurrentInstance()
if (instance) {
  // console.log("instance", instance)
  emit('register', modalMethods, instance.uid)
}

// 获取弹窗标题
const getMergeProps = computed((): Recordable => {
  return {
    ...props,
    ...(unref(propsRef) as any),
  }
})
const getBindValue = computed((): Recordable => {
  const attr = {
    ...attrs,
    ...unref(getMergeProps),
    modelValue: unref(dialogVisible),
  }
  // console.log("attr", attr)
  return attr
})

watch(
  () => unref(dialogVisible),
  (v) => {
    // eslint-disable-next-line vue/custom-event-name-casing
    emit('visible-change', v)
    instance && modalMethods.emitVisible?.(v, instance.uid)
  },
  {
    immediate: false,
  },
)
/**
 * @description: 设置modal参数
 */
function setModalProps(propsData: Partial<BasicDialogProps>): void {
  propsRef.value = deepMerge(unref(propsRef) || ({} as any), propsData)
  if (Reflect.has(propsData, 'dialogVisible')) {
    dialogVisible.value = !!propsData.dialogVisible
  }
}
function handleOk(e: Event) {
  emit('ok', e)
}

// 取消事件
async function handleCancel(e?: Event) {
  e?.stopPropagation()
  if (props.closeFunc && isFunction(props.closeFunc)) {
    const isClose: boolean = await (props.closeFunc as Function)()
    dialogVisible.value = isClose
    return
  }
  dialogVisible.value = false
  emit('cancel', e)
}
// 模态框自带取消事件
function handleClose() {
  // console.log('模态框自带取消事件');
  dialogVisible.value = false
  emit('close')
}
</script>
<template>
  <div>
    <ElDialog v-bind="getBindValue" :show-close="false" @close="handleClose">
      <template #header>
        <slot name="header">
          <div class="flex h-[48px] items-center justify-between rounded-t-[10px] bg-[#EDF2FF]">
            <div class="pl-[32px]">
              <span class="text-[16px] font-semibold text-[#333]">{{ getBindValue.title }}</span>
            </div>
            <slot name="closeicon">
              <div
                v-if="getBindValue.showClose"
                class="icon-font-close flex h-[48px] w-[48px] cursor-pointer items-center justify-center"
                @click="handleCancel"
              >
                <Icon icon="material-symbols:close-small-outline" class="size-6" />
              </div>
            </slot>
          </div>
        </slot>
      </template>
      <slot></slot>
      <template #footer>
        <slot name="footer">
          <DialigFooter v-bind="getBindValue" @cancel="handleCancel" @ok="handleOk">
            <template #[item]="data" v-for="item in Object.keys($slots)">
              <slot :name="item" v-bind="data || {}"></slot>
            </template>
          </DialigFooter>
        </slot>
      </template>
    </ElDialog>
  </div>
</template>
<style lang="scss" scoped>
:deep(.el-dialog__headerbtn) {
  width: 40px;
  height: 40px;
  background: #f6f9ff;
}

:deep(.el-dialog) {
  padding: 0;
  border-radius: 10px;
}

:deep(.el-dialog__header) {
  padding-bottom: 0;
}

.icon-font-close {
  color: #999;

  :hover {
    color: red;
  }
}
</style>
